package com.xiaoshuidi.cloud.module.iot.service.impl.thirdPartImpl;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.module.iot.api.device.vo.AmmeterInfoResModel;
import com.xiaoshuidi.cloud.module.iot.api.device.vo.WaterMeterCommonResponseModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.DeviceGetDailyPowerResModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.OperateThirdDeviceRequestModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.OperateThirdDeviceResponseModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.PullThirdDeviceRequestModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenRequestModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenResponseModel;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDo;
import com.xiaoshuidi.cloud.module.iot.enums.BrandEnum;
import com.xiaoshuidi.cloud.module.iot.enums.PeakValleyEnum;
import com.xiaoshuidi.cloud.module.iot.service.AbstractThirdInstanceService;
import com.xiaoshuidi.cloud.module.iot.uitils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 雷优接口
 */
@Service("leiYouInstanceServiceImpl")
public class LeiYouInstanceServiceImpl extends AbstractThirdInstanceService {

    private final static Logger LOGGER = LoggerFactory.getLogger(LeiYouInstanceServiceImpl.class);

    //雷优获取访问凭证
    @Value("${leiyou.access_token.url}")
    private String leiYouAccessTokenUrl;
    //雷优获取电表信息
    @Value("${leiyou.getAmmeterInfo.url}")
    private String leiyouAmmeterInfo;

    // 雷优成功返回码
    private final static String SUCCESS_CODE = "200000";

    @Override
    public String getBrand() {
        return BrandEnum.LEIYOU.getBrand();
    }

    @Override
    public AccessTokenResponseModel getAccessToken(AccessTokenRequestModel accessTokenRequestModel) throws Exception {
        AccessTokenResponseModel accessTokenResponseModel = new AccessTokenResponseModel();
        JSONObject bodyParam = new JSONObject();
        // 客户端ID
        bodyParam.put("client_id", accessTokenRequestModel.getAppId());
        // 客户端密码
        bodyParam.put("client_secret", accessTokenRequestModel.getAppKey());
        // 授权类型固定值：client_credentials
        bodyParam.put("grant_type", "client_credentials");
        LOGGER.info("雷优获取access_token，请求url:{},请求参数:{}", leiYouAccessTokenUrl, bodyParam.toString());
        String result = HttpRequest.post(leiYouAccessTokenUrl).form(bodyParam)
                .header("Content-Type", "application/x-www-form-urlencoded").execute().body();
        LOGGER.info("雷优获取access_token,返回结果:{}", result);
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            accessTokenResponseModel = new AccessTokenResponseModel();
            // 雷优访问凭证
            String access_token = resultJsonObject.getString("access_token");
            // 令牌类型
            String token_type = resultJsonObject.getString("token_type");
            // 雷优返回的令牌生命周期(秒)
            Long expires_time = resultJsonObject.getLong("expires_in");
            accessTokenResponseModel.setAccessToken(access_token);
            // 设置雷优访问凭证失效时间，比第三方少5分钟
            accessTokenResponseModel.setExpireTime(expires_time - 300);
        }
        // 第三方业务返回逻辑处理,返回获取的token
        return accessTokenResponseModel;
    }

    @Override
    public List<TbDeviceDo> getDevice(PullThirdDeviceRequestModel pullThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public List<TbDeviceDo> initializeDeviceInfo(List<TbDeviceDo> thirdDeviceList, PullThirdDeviceRequestModel pullThirdDeviceRequestModel) {
        // 可能是根据设备ID录入好的
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel addDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel getDynamicDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public AmmeterInfoResModel refreshAmmeterInfo(TbDeviceDo tbDeviceDo, OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        AmmeterInfoResModel ammeterInfoResModel = new AmmeterInfoResModel();
        JSONArray data = this.getRespDataFromLeiYou(operateThirdDeviceRequestModel.getAccessToken(), tbDeviceDo.getDeviceThirdNo(), false);
        if (data != null) {
            JSONObject jsonObject = data.getJSONObject(0);
            JSONArray functions = jsonObject.getJSONArray("functions");
            List<AmmeterInfoResModel.PeakValley> list = new ArrayList<>();
            for (int i = 0; i < functions.size(); i++) {
                JSONObject functionObject = functions.getJSONObject(i);
                String identifier = functionObject.getString("identifier");// 标识符 11X 正向有功电度
                Double value = functionObject.getDouble("value");
                String time = functionObject.getString("time");
                Date reportTime = DateUtils.parseDateInCST(time);
                AmmeterInfoResModel.PeakValley peakValley = new AmmeterInfoResModel.PeakValley();
                peakValley.setType(PeakValleyEnum.convertFromLeiYou(identifier));
                peakValley.setReportTime(reportTime);
                peakValley.setCurrentReading(value);
                list.add(peakValley);
            }
            ammeterInfoResModel.setPeakValleyList(list);
        }
        return ammeterInfoResModel;
    }

    @Override
    public List<DeviceGetDailyPowerResModel> getDailyPower(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel updateDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel frozenDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel unfrozenDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchAmmeterOn(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchAmmeterOff(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel deleteDoorLockPassword(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public WaterMeterCommonResponseModel refreshWatermeterInfo(WaterMeterCommonResponseModel waterMeterCommonResponseModel, OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        waterMeterCommonResponseModel.setOperateResult(false);
        JSONArray data = this.getRespDataFromLeiYou(operateThirdDeviceRequestModel.getAccessToken(), waterMeterCommonResponseModel.getDeviceThirdNo(), true);
        if (data != null) {
            JSONObject jsonObject = data.getJSONObject(0);
            JSONArray functions = jsonObject.getJSONArray("functions");
            for (int i = 0; i < functions.size(); i++) {
                JSONObject functionObject = functions.getJSONObject(i);
                String identifier = functionObject.getString("identifier");
                Double value = functionObject.getDouble("value");
                String time = functionObject.getString("time");
                Date reportTime = DateUtils.parseDateInCST(time);
                if ("12L".equals(identifier)) {
                    waterMeterCommonResponseModel.setOnlineStatus(1);
                    waterMeterCommonResponseModel.setCurrentReading(value);
                    waterMeterCommonResponseModel.setReportTime(reportTime);
                    waterMeterCommonResponseModel.setOperateResult(true);
                }
            }
        }
        return waterMeterCommonResponseModel;
    }

    @Override
    public OperateThirdDeviceResponseModel getDoorLockStatus(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel getOpenLockRecordes(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchColdWaterMeterOff(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchHotWaterMeterOff(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchHotWaterMeterOn(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    @Override
    public OperateThirdDeviceResponseModel switchColdWaterMeterOn(OperateThirdDeviceRequestModel operateThirdDeviceRequestModel) throws Exception {
        return null;
    }

    /**
     * 从雷优设备接口获取读数
     *
     * @param accessToken
     * @param deviceIds 单个设备ID
     * @param isWater
     * @return
     */
    private JSONArray getRespDataFromLeiYou(String accessToken, String deviceIds, boolean isWater) {
        JSONObject bodyParam = new JSONObject();
        bodyParam.put("deviceIds", deviceIds); // WOCJHYDGNM700 第三方设备ID，多个需要用,隔开
        String deviceType = isWater ? "水表" : "电表";
        LOGGER.info("雷优获取{}基本信息，请求url:{},请求参数:{}", deviceType, leiyouAmmeterInfo, bodyParam.toJSONString());
        String result = HttpRequest.get(leiyouAmmeterInfo).form(bodyParam)
                .header("token", accessToken).execute().body();
        LOGGER.info("雷优获取基本信息，返回结果:{}", deviceType, result);
        if (StringUtils.isNotBlank(result)) {
            JSONObject resultJsonObject = JSONObject.parseObject(result);
            String code = resultJsonObject.getString("code");
            if (SUCCESS_CODE.equals(code)) {
                return resultJsonObject.getJSONArray("data");
            }
        }
        return null;
    }
}
